using Engine;

using Game;
namespace IndustrialAge
{
	public class SubsystemMusket6BlockBehavior : SubsystemMusket2BlockBehavior
	{
		public SubsystemGameInfo m_subsystemGameInfo;

		public override bool OnEditInventoryItem(IInventory inventory, int slotIndex, ComponentPlayer componentPlayer)
		{
			componentPlayer.ComponentGui.ModalPanelWidget = componentPlayer.ComponentGui.ModalPanelWidget == null ? new Musket2Widget(inventory, slotIndex) : null;
			return true;
		}

		public override bool OnAim(Ray3 aim, ComponentMiner componentMiner, AimState state)
		{
			Vector3 start = aim.Position, direction = aim.Direction;
			IInventory inventory = componentMiner.Inventory;
			if (inventory != null)
			{
				int activeSlotIndex = inventory.ActiveSlotIndex;
				if (activeSlotIndex >= 0)
				{
					int slotValue = inventory.GetSlotValue(activeSlotIndex),
						slotCount = inventory.GetSlotCount(activeSlotIndex);
					int num = Terrain.ExtractContents(slotValue);
					int data = Terrain.ExtractData(slotValue);
					int num2 = slotValue;
					Vector3 dir = direction;
					if (num == Musket6Block.Index && slotCount > 0)
					{
						//direction = componentMiner.ComponentCreature.ComponentCreatureModel.EyePosition - start;
						if (!m_aimStartTimes.TryGetValue(componentMiner, out double value))
						{
							value = m_subsystemTime.GameTime;
							m_aimStartTimes[componentMiner] = value;
						}
						float num4 = (float)(m_subsystemTime.GameTime - value);
						float num5 = (float)MathUtils.Remainder(m_subsystemTime.GameTime, 1000.0);
						Vector3 v = (float)((componentMiner.ComponentCreature.ComponentBody.IsSneaking ? 0.00999999977648258 : 0.0299999993294477) + 0.200000002980232 * MathUtils.Saturate((num4 - 6.5f) / 40f)) * new Vector3
						{
							X = SimplexNoise.OctavedNoise(num5, 2f, 3, 2f, 0.5f),
							Y = SimplexNoise.OctavedNoise(num5 + 100f, 2f, 3, 2f, 0.5f),
							Z = SimplexNoise.OctavedNoise(num5 + 200f, 2f, 3, 2f, 0.5f)
						};

						direction = Vector3.Normalize(direction+v);
						switch (state)
						{
							case AimState.InProgress:
								{
									if (num4 >= 50f)
									{
										componentMiner.ComponentCreature.ComponentCreatureSounds.PlayMoanSound();
										return true;
									}
									if (num4 > 0.2f && !Musket2Block.GetHammerState(Terrain.ExtractData(num2)))
									{
										num2 = Terrain.MakeBlockValue(num, 0, Musket2Block.SetHammerState(Terrain.ExtractData(num2), true));
										m_subsystemAudio.PlaySound("Audio/HammerCock", 1f, m_random.Float(-0.1f, 0.1f), 0f, 0f);
									}
									var view2 = componentMiner.ComponentPlayer.GameWidget;
									ComponentFirstPersonModel componentFirstPersonModel = componentMiner.Entity.FindComponent<ComponentFirstPersonModel>();
									if (componentFirstPersonModel != null)
									{
										ComponentPlayer componentPlayer2 = componentMiner.ComponentPlayer;
										//fix me
										//if (componentPlayer2 != null) componentPlayer2.ComponentGui.ShowAimingSights(start, direction);
										componentFirstPersonModel.ItemOffsetOrder = new Vector3(-0.21f, 0.15f, 0.08f);
										componentFirstPersonModel.ItemRotationOrder = new Vector3(-0.7f, 0f, 0f);
									}
									componentMiner.ComponentCreature.ComponentCreatureModel.AimHandAngleOrder = 1.4f;
									componentMiner.ComponentCreature.ComponentCreatureModel.InHandItemOffsetOrder = new Vector3(-0.08f, -0.08f, 0.07f);
									componentMiner.ComponentCreature.ComponentCreatureModel.InHandItemRotationOrder = new Vector3(-1.7f, 0f, 0f);
									break;
								}

							case AimState.Cancelled:
								
								if (Musket2Block.GetHammerState(Terrain.ExtractData(num2)))
								{
									num2 = Terrain.MakeBlockValue(num, 0, Musket2Block.SetHammerState(Terrain.ExtractData(num2), false));
									m_subsystemAudio.PlaySound("Audio/HammerUncock", 1f, m_random.Float(-0.1f, 0.1f), 0f, 0f);
								}
								m_aimStartTimes.Remove(componentMiner);
								break;
							case AimState.Completed:
								{
									var vvv2 = new Vector3(0f, 0f, 0f);
									var view3 = componentMiner.ComponentPlayer.GameWidget;
									//view3.ActiveCamera = view3.ActiveCamera is TelescopeCamera2 ? view3.FindCamera<FppCamera>(true) : (Camera)new TelescopeCamera2(view3);
									bool flag = false;
									int value2 = 0;
									int num6 = 0;
									float s = 0f;
									dir = Vector3.Normalize(vvv2);
									Vector3 vector = Vector3.Zero;
									Musket2Block.LoadState loadState = Musket2Block.GetLoadState(data);
									if (Musket4Block.GetBulletNum(Terrain.ExtractData(inventory.GetSlotValue(activeSlotIndex))) > 0)
									{
										flag = true;
										value2 = Terrain.MakeBlockValue(214, 0, BulletBlock.SetBulletType(0, BulletBlock.BulletType.BuckB));
										s = 180f;
										num6 = 12;
										vector = new Vector3(0.001f, 0.001f, 0.001f);
									}
									if (flag)
									{
										{
											//componentMiner.ComponentCreature.ComponentCreatureModel.EyePosition =Vector3.Normalize(vvv2);
											Vector3 eyePosition = componentMiner.ComponentCreature.ComponentCreatureModel.EyePosition;
											Matrix matrix = componentMiner.ComponentCreature.ComponentBody.Matrix;
											Vector3 vector2 = eyePosition + matrix.Right * 0.3f - matrix.Up * 0.2f;
											var vector3 = Vector3.Normalize(vector2 + direction * 10f - vector2);
											var vector31 = Vector3.Normalize(direction);
											var vector4 = Vector3.Normalize(Vector3.Cross(vector3, Vector3.UnitY));
											var v3 = Vector3.Normalize(Vector3.Cross(vector3, vector4));
											for (int i = 0; i < num6; i++)
											{
												Vector3 v4 = m_random.Float(-vector.X, vector.X) * vector4 + m_random.Float(-vector.Y, vector.Y) * v3 + m_random.Float(-vector.Z, vector.Z) * vector3;
												Projectile projectile = m_subsystemProjectiles.FireProjectile(value2, vector2, s * (vector31 + v4*50f), Vector3.Zero, componentMiner.ComponentCreature);
												if (projectile != null)
													projectile.ProjectileStoppedAction = ProjectileStoppedAction.Disappear;
											}
											m_subsystemAudio.PlaySound("Audio/MusketFire", 1f, m_random.Float(-0.1f, 0.1f), componentMiner.ComponentCreature.ComponentCreatureModel.EyePosition, 10f, true);
											var vector312 = Vector3.Normalize(componentMiner.ComponentPlayer.GameWidget.ActiveCamera.ViewDirection);
											m_subsystemParticles.AddParticleSystem(new GunSmokeParticleSystem2(SubsystemTerrain, vector2 + 1.3f * vector312, vector312));
											m_subsystemNoise.MakeNoise(vector2, 1f, 60f);
											//componentMiner.ComponentCreature.ComponentBody.ApplyImpulse(-1f * vector3);
											int value23 = Terrain.ExtractData(inventory.GetSlotValue(activeSlotIndex));
											int num44 = Musket6Block.GetBulletNum(value23);
											componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage((num44 - 1).ToString(),Color.White, blinking: true, playNotificationSound: false);
											inventory.RemoveSlotItems(activeSlotIndex, 1);
											inventory.AddSlotItems(activeSlotIndex, Terrain.MakeBlockValue(Musket6Block.Index, 0, Musket6Block.SetBulletNum(num44 - 1)), 1);
											if (Utils.Random.Bool(0.1f))
												componentMiner.DamageActiveTool(1);
										}
									}
									//if (Musket2Block.GetHammerState(Terrain.ExtractData(num2)))
									//{
									//num2 = Terrain.MakeBlockValue(Terrain.ExtractContents(num2), 0, Musket2Block.SetHammerState(Terrain.ExtractData(num2), false));
									//m_subsystemAudio.PlaySound("Audio/HammerRelease", 1f, m_random.Float(-0.1f, 0.1f), 0f, 0f);
									//}
									var view5 = componentMiner.ComponentPlayer.GameWidget;
									view5.ActiveCamera = view5.FindCamera<FppCamera>(true);
									m_aimStartTimes.Remove(componentMiner);
									break;
								}
						}
					}
					if (num2 != slotValue)
					{
						inventory.RemoveSlotItems(activeSlotIndex, 1);
						inventory.AddSlotItems(activeSlotIndex, num2, 1);
					}
					//if (num2 != slotValue)
					//{
					//	inventory.RemoveSlotItems(activeSlotIndex, 1);
					//	inventory.AddSlotItems(activeSlotIndex, num2, 1);
					//}
				}
			}
			return false;
		}

		public override int GetProcessInventoryItemCapacity(IInventory inventory, int slotIndex, int value)
		{
			return value != Terrain.MakeBlockValue(521, 0, Bullet2Block.SetBulletType(0, Bullet2Block.BulletType.BucketBullet)) || Musket6Block.GetBulletNum(Terrain.ExtractData(inventory.GetSlotValue(slotIndex))) > 11
				? 0
				: 1;
		}

		public override void ProcessInventoryItem(IInventory inventory, int slotIndex, int value, int count, int processCount, out int processedValue, out int processedCount)
		{
			processedValue = value;
			processedCount = count;
			//processCount = count;
			int value22 = Terrain.ExtractData(inventory.GetSlotValue(slotIndex));
			int num = Musket6Block.GetBulletNum(value22);
			if (processCount + num < 13)
			{
				//var loadState = Musket2Block.GetLoadState(Terrain.ExtractData(inventory.GetSlotValue(slotIndex)));

				processedValue = 0;
				processedCount = 0;
				//processCount = 0;
				inventory.RemoveSlotItems(slotIndex, 1);
				inventory.AddSlotItems(slotIndex, Terrain.MakeBlockValue(Musket6Block.Index, 0, Musket6Block.SetBulletNum(num + processCount)), 1);
			}
		}
	}




	public class SubsystemMusket7BlockBehavior : SubsystemMusket2BlockBehavior
	{
		public SubsystemGameInfo m_subsystemGameInfo;

		public override bool OnEditInventoryItem(IInventory inventory, int slotIndex, ComponentPlayer componentPlayer)
		{
			componentPlayer.ComponentGui.ModalPanelWidget = componentPlayer.ComponentGui.ModalPanelWidget == null ? new Musket2Widget(inventory, slotIndex) : null;
			return true;
		}

		public override bool OnAim(Ray3 aim, ComponentMiner componentMiner, AimState state)
		{
			Vector3 start = aim.Position, direction = aim.Direction;
			IInventory inventory = componentMiner.Inventory;
			if (inventory != null)
			{
				int activeSlotIndex = inventory.ActiveSlotIndex;
				if (activeSlotIndex >= 0)
				{
					int slotValue = inventory.GetSlotValue(activeSlotIndex),
						slotCount = inventory.GetSlotCount(activeSlotIndex);
					int num = Terrain.ExtractContents(slotValue);
					int data = Terrain.ExtractData(slotValue);
					int num2 = slotValue;
					int num3 = 0;
					//int value23 = Terrain.ExtractData(inventory.GetSlotValue(activeSlotIndex));
					//int num44 = Musket6Block.GetBulletNum(value23);
					Vector3 dir = direction;
					if (num == Musket7Block.Index && slotCount > 0)
					{
						//direction = componentMiner.ComponentCreature.ComponentCreatureModel.EyePosition - start;
						if (!m_aimStartTimes.TryGetValue(componentMiner, out double value))
						{
							value = m_subsystemTime.GameTime;
							m_aimStartTimes[componentMiner] = value;
						}
						float num4 = (float)(m_subsystemTime.GameTime - value);
						float num5 = (float)MathUtils.Remainder(m_subsystemTime.GameTime, 1000.0);
						Vector3 v = (float)((componentMiner.ComponentCreature.ComponentBody.IsSneaking ? 0.00999999977648258 : 0.0299999993294477) + 0.200000002980232 * MathUtils.Saturate((num4 - 6.5f) / 40f)) * new Vector3
						{
							X = SimplexNoise.OctavedNoise(num5, 2f, 3, 2f, 0.5f),
							Y = SimplexNoise.OctavedNoise(num5 + 100f, 2f, 3, 2f, 0.5f),
							Z = SimplexNoise.OctavedNoise(num5 + 200f, 2f, 3, 2f, 0.5f)
						};

						direction = Vector3.Normalize(direction + v);
						switch (state)
						{
							case AimState.InProgress:
								{
									if (num4 >= 50f)
									{
										componentMiner.ComponentCreature.ComponentCreatureSounds.PlayMoanSound();
										return true;
									}
									if (num4 > 0.2f && !Musket2Block.GetHammerState(Terrain.ExtractData(num2)))
									{
										num2 = Terrain.MakeBlockValue(num, 0, Musket2Block.SetHammerState(Terrain.ExtractData(num2), true));
										m_subsystemAudio.PlaySound("Audio/HammerCock", 1f, m_random.Float(-0.1f, 0.1f), 0f, 0f);
									}
									var view2 = componentMiner.ComponentPlayer.GameWidget;
									ComponentFirstPersonModel componentFirstPersonModel = componentMiner.Entity.FindComponent<ComponentFirstPersonModel>();
									if (componentFirstPersonModel != null)
									{
										ComponentPlayer componentPlayer2 = componentMiner.ComponentPlayer;
										//fix me
										//if (componentPlayer2 != null) componentPlayer2.ComponentGui.ShowAimingSights(start, direction);
										componentFirstPersonModel.ItemOffsetOrder = new Vector3(-0.21f, 0.15f, 0.08f);
										componentFirstPersonModel.ItemRotationOrder = new Vector3(-0.7f, 0f, 0f);
									}
									componentMiner.ComponentCreature.ComponentCreatureModel.AimHandAngleOrder = 1.4f;
									componentMiner.ComponentCreature.ComponentCreatureModel.InHandItemOffsetOrder = new Vector3(-0.08f, -0.08f, 0.07f);
									componentMiner.ComponentCreature.ComponentCreatureModel.InHandItemRotationOrder = new Vector3(-1.7f, 0f, 0f);
									break;
								}

							case AimState.Cancelled:

								if (Musket2Block.GetHammerState(Terrain.ExtractData(num2)))
								{
									num2 = Terrain.MakeBlockValue(num, 0, Musket2Block.SetHammerState(Terrain.ExtractData(num2), false));
									m_subsystemAudio.PlaySound("Audio/HammerUncock", 1f, m_random.Float(-0.1f, 0.1f), 0f, 0f);
								}
								m_aimStartTimes.Remove(componentMiner);
								break;
							case AimState.Completed:
								{
									int dur = GetDamage(slotValue);
									if (dur > 3889 || Musket4Block.GetBulletNum(Terrain.ExtractData(inventory.GetSlotValue(activeSlotIndex))) <= 0)
										return false;
									m_subsystemAudio.PlaySound("Audio/MusketFire", 1f, m_random.Float(-0.1f, 0.1f), componentMiner.ComponentCreature.ComponentCreatureModel.EyePosition, 10f, true);
									Vector3 eyePosition = componentMiner.ComponentCreature.ComponentCreatureModel.EyePosition;
									Matrix matrix = componentMiner.ComponentCreature.ComponentBody.Matrix;
									Vector3 vectorp = eyePosition + matrix.Right * 0.3f - matrix.Up * 0.2f;
									ComponentNPlayer miner2 = componentMiner.Entity.FindComponent<ComponentNPlayer>();
									Ray3 ray = new Ray3(vectorp, direction);
									var result = componentMiner.Raycast<TerrainRaycastResult>(ray,RaycastMode.Digging);
									var body = componentMiner.Raycast<BodyRaycastResult>(ray,RaycastMode.Gathering,false,true,false);
									float end = 500f;
									for (int n1 = 0; n1 < 20; n1++)
									{
										if (miner2 != null)
										{
											//componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage((99999999).ToString(), blinking: true, playNotificationSound: false);
											result = miner2.PickTerrainForDigging3(vectorp, direction, 500f);
											body = miner2.PickBody2(vectorp, direction, 500f);
										}
										//componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage((11111111).ToString(), blinking: true, playNotificationSound: false);
										
										if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance))
										{
											ComponentCreature cre1 = body.Value.ComponentBody.Entity.FindComponent<ComponentCreature>();
											if (cre1 != null)
											{
												if (cre1.ComponentHealth.AttackResilience > 1000)
												{
													cre1.Entity.FindComponent<ComponentHealth>()?.Injure(600f / cre1.ComponentHealth.AttackResilience, componentMiner.ComponentCreature, false, "Killed by Gauss");
													num3 = 100;
													if (num3 > 0)
														componentMiner.DamageActiveTool(num3);
													int value231 = Terrain.ExtractData(inventory.GetSlotValue(activeSlotIndex));
													int num441 = Musket7Block.GetBulletNum(value231);
													componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage((num441 - 1).ToString(),Color.White, blinking: true, playNotificationSound: false);
													inventory.RemoveSlotItems(activeSlotIndex, 1);
													inventory.AddSlotItems(activeSlotIndex, Terrain.MakeBlockValue(Musket7Block.Index, 0, Musket7Block.SetBulletNum(num441 - 1)), 1);
													//num2 = Terrain.MakeBlockValue(Terrain.ExtractContents(num2), 0, Musket5Block.SetHammerState(Terrain.ExtractData(num2), false));
													Utils.SubsystemLaser.MakeLightningStrike2(new Vector3(vectorp.X, vectorp.Y, vectorp.Z) + 1.1f * direction, new Vector3(vectorp.X, vectorp.Y, vectorp.Z) + end * direction);
													m_aimStartTimes.Remove(componentMiner);
													return false;
												}
												else
												{
													var list = cre1.Entity.FindComponent<ComponentLoot>().m_lootList;
													if (list != null)
													{
														for (int i1 = 0; i1 < list.Count; i1++)
														{
															for (int i2 = 0; i2 < list[i1].MaxCount; i2++)
															{
																Utils.SubsystemPickables.AddPickable(list[i1].Value, 1, body.Value.ComponentBody.m_position, new Vector3(0f, 1f, 0f), null);
															}
														}
													}

													Utils.SubsystemParticles.AddParticleSystem(new KillParticleSystem(Utils.SubsystemTerrain, cre1.ComponentBody.Position, 1f));
													end = MathUtils.Abs(Vector3.Distance(cre1.ComponentBody.Position, vectorp));
													//end = vectorp + direction * 100f;
													if (cre1.Entity.FindComponent<ComponentNPlayer>() != null)
													{
														cre1.Entity.FindComponent<ComponentHealth>()?.Injure(1f, null, false, "Killed by Gauss");
													}
													else
														Project.RemoveEntity(cre1.Entity, true);
												}
											}
										}
										else if (result.HasValue)
										{
											Point3 point = result.Value.CellFace.Point;
											int value2 = Utils.Terrain.GetCellValueFast(point.X, point.Y, point.Z);
											int value3 = Utils.Terrain.GetCellContentsFast(point.X, point.Y, point.Z);
											var block = BlocksManager.Blocks[value3];
											if (value != 0 && block.IsPlaceable)
											{

												Utils.SubsystemTerrain.DestroyCell(5, point.X, point.Y, point.Z, 0, false, false);


											}
										}
									}
									num3 = 100;
									if (num3 > 0)
										componentMiner.DamageActiveTool(num3);

									int value232 = Terrain.ExtractData(inventory.GetSlotValue(activeSlotIndex));
									int num442 = Musket7Block.GetBulletNum(value232);
									componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage((num442 - 1).ToString(),Color.White, blinking: true, playNotificationSound: false);
									inventory.RemoveSlotItems(activeSlotIndex, 1);
									inventory.AddSlotItems(activeSlotIndex, Terrain.MakeBlockValue(Musket7Block.Index, 0, Musket7Block.SetBulletNum(num442 - 1)), 1);
									//num2 = Terrain.MakeBlockValue(Terrain.ExtractContents(num2), 0, Musket5Block.SetHammerState(Terrain.ExtractData(num2), false));
									Utils.SubsystemLaser.MakeLightningStrike2(new Vector3(vectorp.X, vectorp.Y, vectorp.Z) + 1.1f * direction, new Vector3(vectorp.X, vectorp.Y, vectorp.Z) + end * direction);
									m_aimStartTimes.Remove(componentMiner);

									//m_subsystemAudio.PlaySound("Audio/MusketFire", 1f, m_random.Float(-0.1f, 0.1f), componentMiner.ComponentCreature.ComponentCreatureModel.EyePosition, 10f, true);
									//var vector312 = Vector3.Normalize(componentMiner.ComponentPlayer.View.ActiveCamera.ViewDirection);
									//m_subsystemParticles.AddParticleSystem(new GunSmokeParticleSystem2(SubsystemTerrain, vector2 + 1.3f * vector312, vector312));

									break;

								}
						}
					}
					if (num2 != slotValue)
					{
						inventory.RemoveSlotItems(activeSlotIndex, 1);
						inventory.AddSlotItems(activeSlotIndex, num2, 1);
					}
					//if (num2 != slotValue)
					//{
					//	inventory.RemoveSlotItems(activeSlotIndex, 1);
					//	inventory.AddSlotItems(activeSlotIndex, num2, 1);
					//}
				}
			}
			return false;
		}

		public override int GetProcessInventoryItemCapacity(IInventory inventory, int slotIndex, int value)
		{
			return value != Terrain.MakeBlockValue(521, 0, Bullet2Block.SetBulletType(0, Bullet2Block.BulletType.TiBullet)) || Musket7Block.GetBulletNum(Terrain.ExtractData(inventory.GetSlotValue(slotIndex))) > 49
				? 0
				: 1;
		}

		public override void ProcessInventoryItem(IInventory inventory, int slotIndex, int value, int count, int processCount, out int processedValue, out int processedCount)
		{
			processedValue = value;
			processedCount = count;
			//processCount = count;
			int value22 = Terrain.ExtractData(inventory.GetSlotValue(slotIndex));
			int num = Musket7Block.GetBulletNum(value22);
			if (processCount + num < 51)
			{
				//var loadState = Musket2Block.GetLoadState(Terrain.ExtractData(inventory.GetSlotValue(slotIndex)));

				processedValue = 0;
				processedCount = 0;
				//processCount = 0;
				inventory.RemoveSlotItems(slotIndex, 1);
				inventory.AddSlotItems(slotIndex, Terrain.MakeBlockValue(Musket7Block.Index, 0, Musket7Block.SetBulletNum(num + processCount)), 1);
			}
		}

		public static int GetDamage(int value)
		{
			return (Terrain.ExtractData(value) >> 4) & 4095;
		}
	}
}